#pragma once

#include <functional>
#include <pthread.h>
#include <vector>
#include <unistd.h>
#include "Sock.hpp"

using func_t = std::function<void(int)>;
namespace my_tcpserver
{
    // 声明一下
    class TcpServer;

    class ThreadData
    {
    public:
        ThreadData(int sock, TcpServer *server):_sock(sock), _server(server)
        {}
        ~ThreadData()
        {}
    public:
        int _sock;
        TcpServer *_server;
    };

    class TcpServer
    {
    private:
        static void *ThreadRoutine(void *args)
        {
            // 线程分离,当线程执行完毕，让OS回收
            pthread_detach(pthread_self());
            ThreadData *td = static_cast<ThreadData *>(args);
            
            // 让这个线程去执行某个函数
            td->_server->Execute(td->_sock);
            close(td->_sock); // 关闭服务这个客户端的套接字
            std::cout<<"服务这个客户端的套接字关闭"<<std::endl;
            // delete td;
            return nullptr;
        }
    public:
        TcpServer(const uint16_t& port, const std::string& ip = "0.0.0.0")
        {
            // 创建套接字
            _listensock = _sock.Socket();
            // bind
            _sock.Bind(_listensock, ip, port);
            // 监听
            _sock.Listen(_listensock);

        }

        // 启动客户端
        void Start()
        {
            for(;;)
            {
                std::string clientIp;
                uint16_t clientPort;

                int servicesock = _sock.Accept(_listensock, &clientIp, &clientPort);
                if(servicesock == -1)
                    continue;
                logMessage(NORMAL, "create new link success, servicesock: %d", servicesock);

                // 创建线程去服务客户端
                pthread_t tid;
                ThreadData *td = new ThreadData(servicesock, this);
                pthread_create(&tid, nullptr, ThreadRoutine, td);
            }
        }

        // 绑定一个方法
        void BindService(func_t func)
        {
            _func.push_back(func);
        }

        // 执行方法
        void Execute(int sock)
        {
            for(auto& func : _func)
            {
                func(sock);
            }
        }
        ~TcpServer()
        {
            if(_listensock >= 0)
            {
                close(_listensock);
            }
        }
    private:
        Sock _sock;
        std::vector<func_t> _func;
        int _listensock;
    };
}